﻿using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace DotNetCommon;
/// <summary>
/// 异步延迟加载实现, 参照: <see href="https://devblogs.microsoft.com/pfxteam/asynclazyt/"/>
/// <example>
/// <code>
/// class Student
/// {
///     public AsyncLazy&lt;Book&gt; Book = new AsyncLazy&lt;Book&gt;(() => new Book());
/// }
/// 
/// public class Program
/// {
///     public static async Task Main(string[] args)
///     {
///         var student=new Student();
///         var book=await student.Book;
///     }
/// }
/// </code>
/// </example>
/// </summary>
public sealed class AsyncLazy<T> : Lazy<Task<T>>
{
    /// <summary>
    /// 根据对象创建逻辑构造异步延迟加载对象
    /// </summary>
    /// <example>
    /// <code>
    /// new AsyncLazy&lt;Book&gt;(() => new Book());
    /// </code>
    /// </example>
    /// <param name="valueFactory">数据模型创建逻辑</param>
    public AsyncLazy(Func<T> valueFactory) :
        base(() => Task.Factory.StartNew(valueFactory))
    { }

    /// <summary>
    /// 根据对象创建逻辑构造异步延迟加载对象
    /// </summary>
    public AsyncLazy(Func<Task<T>> taskFactory) :
        base(() => Task.Factory.StartNew(taskFactory).Unwrap())
    { }

    /// <summary>
    /// 支持 <c>await</c>语法
    /// </summary>
    /// <returns></returns>
    public TaskAwaiter<T> GetAwaiter() => Value.GetAwaiter();
}